/*
 * main.cpp
 *
 *  Created on: 04/02/2013
 *      Author: vagner
 */

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include "Grafo.h"
#include "IOManager.h"
#include "RamdomManager.h"
#include "Colonia.h"
#include <sstream>
#include <iomanip>

using namespace tp2cn;

int main(int argc, char **argv) {

	IOManager iomanager;
	std::vector<int> valoresLidos;
	std::string linhaLida;
	int numMedianas;
	int numVertices;
	int verticesLidos = 0;
	int interacoes= 0;
	int numFormigas;
	float txInicialFeromonio;
	float txEvaporacaoFeromonio;
	/* No modo de operação 0 a posição inicial do formigueiro é escolhida aleatoriamente entre
	 entre 0 e MA_X(maior valor da abcissa de um vertice), para os valores da abcissa e entre 0 e
	 MAX_Y (maior valor de ordenada encontrado) para os valores da ordenada. No modo de operação
	 1 a a posição inicial do formigueiro é definido como o ponto médido dos vértices.Para maiores detalhes
	 vide a documentação da aplicação.
	 */
	int modoOperacao;
	int MAX_X = 0;
	int MAX_Y = 0;
	Vertice auxVertice, posicaoColonia;
	int i;
	std::stringstream outString;

	if (iomanager.validaEntrada(argc)) {

		iomanager.abreArquivoEntrada(argv[2]);
		iomanager.abreArquivoSaida(argv[4]);

		interacoes = std::atoi(argv[6]);
		numFormigas = std::atoi(argv[8]);
		txInicialFeromonio = std::atof(argv[10]);
		txEvaporacaoFeromonio = std::atof(argv[12]);
		modoOperacao = std::atoi(argv[14]);

		/*
		 * Lendo a primeira linha do arquivo para recuperar o número
		 * de vértices e de medianas do problema
		 */
		linhaLida = iomanager.leiaProxLinha();
		iomanager.splitEmVetor(linhaLida, valoresLidos);
		numVertices = valoresLidos.at(0);
		numMedianas = valoresLidos.at(1);
		valoresLidos.clear();

		//O formigueiro sera um pseudovertice de onde sairão inicialmente as formigas.

	    Grafo grafo(numVertices+1);


		while ((linhaLida = iomanager.leiaProxLinha()) != "EOF") {

			iomanager.splitEmVetor(linhaLida, valoresLidos);

			auxVertice.idVertice = verticesLidos;
			auxVertice.coorX = valoresLidos.at(0);
			auxVertice.coorY = valoresLidos.at(1);
			auxVertice.capacidade = valoresLidos.at(2);
			auxVertice.demanda = valoresLidos.at(3);
			auxVertice.numeroFormigas = 0;
			auxVertice.atendidoPor  = N_ATENDIDO;

			if(auxVertice.coorX > MAX_X){
				MAX_X = auxVertice.coorX;
			}
			if(auxVertice.coorY > MAX_Y){
				MAX_Y = auxVertice.coorY;
			}

			grafo.insereVerticeNaPosicao(auxVertice, verticesLidos);
			valoresLidos.clear();
			verticesLidos++;
		}

		Colonia colonia(numMedianas,numVertices+1, &grafo,numFormigas,txInicialFeromonio,txEvaporacaoFeromonio);


		for (i = 0; i < interacoes; i++) {

			colonia.definePosicaoInicial(MAX_X, MAX_Y,modoOperacao);

			posicaoColonia = colonia.getPosicaoColonia();

			colonia.selecionaMedianas();

			colonia.reposicionaFormigas();

			colonia.defineAtendimentos();

			outString << i <<": " << posicaoColonia.coorX << " " << posicaoColonia.coorY<< " ";

			outString << colonia.showMedianas();

			outString << colonia.getUltimaSolucao();

			iomanager.escreveArquivoSaida(outString.str());

			outString.str("");

			colonia.retornaFomigueiro();
			//colonia.reiniciaMatrizFeromonio(txInicialFeromonio);

		}

		std::cout << "Melhor solução encontrada " << std::fixed << std::setprecision(2) << colonia.getMelhorSolucao() << std::endl;

		std::cout << "Medianas: " << colonia.showMelhoresMedianas() << std::endl;

		std::cout << "Para maiores detalhes acesso o arquivo disponível em: ~" << argv[4]
				<< std::endl;

		std::cout << "Everything is gonna be alright!!!" << std::endl;

	} else {
		std::cout
				<< "Número de argumentos inválidos, vide documentação. O programa será encerrado."
				<< std::endl;
	}
	return EXIT_SUCCESS;
}

